香港などのオプトインリージョンにスイッチロールしてCLIコマンドを実行したらAuthFailureになった件について
こんにちは、カトアキです。
タイトルの通りうまくいかなくて色々と調査しました。 原因と対応方法が分かったので、自分への備忘録&同じ用に悩むだれか向けに記事を書くことにしました。
なにが起こったの?
以下の流れでアカウントBの香港リージョンに ec2 describe-regionsを実行したところエラーが返ってきました。
前提
- アカウントAのIAMユーザがスイッチロールするためのロールがアカウントBに用意されている
流れ
アカウントBのロールにスイッチロール
sts assume-roleでセッショントークンを取得
aws sts assume-role \ --role-arn "arn:aws:iam::{BのアカウントID}:role/katoaki” \ --role-session-name katoaki@{BのアカウントID}
{ "Credentials": { "AccessKeyId": “{xxx}“, "SecretAccessKey": “{yyy}”, "SessionToken": “{zzz}”, "Expiration": "2019-11-22T14:04:11Z" }, "AssumedRoleUser": { "AssumedRoleId": “aaa”, "Arn": "arn:aws:sts::{AのアカウントID}:assumed-role/katoaki/katoaki@{BのアカウントID}” } }
セッション情報を環境変数にセット
export AWS_ACCESS_KEY_ID={xxx} export AWS_SECRET_ACCESS_KEY={yyy} export AWS_SESSION_TOKEN={zzz}
香港リージョンのインスタンス情報の参照
describe-regionsを実行
aws ec2 describe-instances --region ap-east-1
An error occurred (AuthFailure) when calling the DescribeInstances operation: AWS was not able to validate the provided access credentials
ちなみにこの時、ap-northeast-1を指定した場合にはエラーは返ってきません。
aws ec2 describe-instances --region ap-northeast-1
{ "Reservations": [] }
なぜエラーになったの?
理由は、実は上記の操作を行った際に、セッションの取得をグローバルのSTSエンドポイントから取得しており、かつ「デフォルトで有効になっている AWS リージョンでのみ有効」の設定になっていたためです。(sts assume-roleを実行したときにリージョンを指定しない場合、デフォルトのグローバルSTSエンドポイントが利用されます。また、グローバルSTSエンドポイントのデフォルト設定が「デフォルトで有効になっている AWS リージョンでのみ有効」です。)
こちらのページ*1 に書いてあるとおり、オプトインリージョン(香港やバーレーンのリージョンなど、デフォルトで有効になっていないリージョン*2 )にアクセスするためには、グローバルのSTSエンドポイントのリージョン互換性の設定を「すべての AWS リージョンで有効」にする必要があります。
~バージョン 1 トークンは、デフォルトで利用できる AWS リージョンでのみ有効です。これらのトークンは、アジアパシフィック (香港) など手動で有効になっているリージョンでは動作しません。バージョン 2 のトークンはすべてのリージョンで有効です。~
*1 AWS リージョンでの AWS STS の管理 - AWS Identity and Access Management https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html
*2 AWS リージョンの管理 - AWS 全般のリファレンス https://docs.aws.amazon.com/ja_jp/general/latest/gr/rande-manage.html
対応方法
アカウントAのSTSの設定変更を行い、グローバルSTSエンドポイントでバージョン2トークンを使う設定(「すべてのAWSリージョンで有効」を設定)に変更する
もしくは、リージョンのSTSエンドポイントを使って sts assumeroleを実行します。これならグローバルのSTSエンドポイントの設定は不要です。
aws sts assume-role \ --role-arn "arn:aws:iam::{BのアカウントID}:role/katoaki” \ --role-session-name katoaki@{BのアカウントID} --endpoint https://sts.ap-northeast-1.amazonaws.com
結果
グローバルのSTSエンドポイントの設定を変更してv2トークンを使うようにした結果、このようになります。エラーが出なくなりました!
おわりに
これ、AuthErrorって出ても直感的にどうしたらいいのかわかりにくいですよね。アカウントBのSTSの設定を変更してみたりと当初は迷走していました。
実はしばらく前にこの機能のアップデートの情報が出てたので知っていればあー、あれかってなるんですけど(それでもこの件すぐに理解しづらい気がしますけど!)
> AWS Security Token Service (STS) で、すべての AWS リージョンと互換性のあるセッショントークンがグローバル STS エンドポイントにより発行されるようになりました https://aws.amazon.com/jp/about-aws/whats-new/2019/04/aws-security-token-service-sts-now-supports-enabling-the-global-sts-endpoint-to-issue-session-tokens-compatible-with-all-aws-regions/
自分への備忘録として書いてますが、だれかの助けになれば幸いです。